#!/bin/bash

# check number of arguments
if [ "$#" -eq 0 ]; then
  echo "$0 is NOT recommended to be directly used" >&2
  exit 1
fi

BINDIR=$(dirname $0)
LINK=$BINDIR/llvm-link
OPT=$BINDIR/opt
CLAMP_DEVICE=$BINDIR/clamp-device
CLAMP_EMBED=$BINDIR/clamp-embed
HLC_DIR=$BINDIR/../../hlc
HLC_LLVM_LINK=$HLC_DIR/bin/llvm-link
HLC_OPT=$HLC_DIR/bin/opt
HLC_LLC=$HLC_DIR/bin/llc
HLC_ASM_DIR=$BINDIR/../../HSAILasm
HLC_ASM=$HLC_ASM_DIR/HSAILasm


HSA_LLVM_BIN_DIR="${BASH_SOURCE%/*}/../../llvm/bin"
if [ -d "$HSA_LLVM_BIN_DIR" ]; then
    HLC_DIR=$HSA_LLVM_BIN_DIR
    HLC_LLVM_LINK=$HSA_LLVM_BIN_DIR/llvm-link
    HLC_OPT=$HSA_LLVM_BIN_DIR/opt
    HLC_LLC=$HSA_LLVM_BIN_DIR/llc
fi

################
# Verbose flag
################

VERBOSE=0

################
# GPU targets
################

LOWER_OPENCL=@HAS_OPENCL@
LOWER_HSA=@HAS_HSA@
LOWER_HOF=@HAS_HSA_HOF@
AMDGPU_TARGET=@AMDGPU_TARGET@

################
# Sanity check for HSAIL backend
################

HSA_USE_AMDGPU_BACKEND=@HSA_USE_AMDGPU_BACKEND@

if [ $HSA_USE_AMDGPU_BACKEND == "ON" ]; then
  KM_USE_AMDGPU="${KM_USE_AMDGPU:=1}"
fi

if [ $LOWER_HSA == 1 ]; then
  if [ -d $HLC_DIR ] && [ -e $HLC_LLVM_LINK ] && [ -e $HLC_OPT ] && [ -e $HLC_LLC ] && [ -d $HLC_ASM_DIR ] && [ -e $HLC_ASM ] || [ $KM_USE_AMDGPU -eq 1 ] ; then 
    # all HSA tools are available
    LOWER_HSA=1
  else
    # disable HSA lowering in case any of the required tools is missing
    echo "WARNING: Missing HSA toolchain.  Disable HSA target."
    LOWER_HSA=0
  fi
fi

################
# Sanity check for HSA offline finalization
################

if [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 1 ]; then
  # Path to HOF
  HOF_BIN=@HOF_BIN@

  if [ -d $HOF_BIN ] && ( [ -e $HOF_BIN/hof ] || [ -e $HOF_BIN/amdhsafin ] ); then
    # all HOF tools are available
    HCC_NOISA="${HCC_NOISA:=0}"
    if [ $HCC_NOISA == "1" ]; then
      echo "WARNING: HSA offline finalization explicitely disabled."
      LOWER_HOF=0
    else
      LOWER_HOF=1
    fi
  else
    # disable HOF in case any of the required tools is missing
    echo "WARNING: Missing HOF tools.  Disable HSA offline finalization."
    LOWER_HOF=0
  fi
fi

################
# link
################

LINK_KERNEL_ARGS=""
LINK_HOST_ARGS=""
LINK_OTHER_ARGS=""
LINK_CPU_ARG=""

TEMP_DIR=`mktemp -d`

# a file which contains the list of __cxxamp_serialize symbols in each CPU object file
CXXAMP_SERIALIZE_SYMBOL_FILE=$TEMP_DIR/symbol.txt
touch $CXXAMP_SERIALIZE_SYMBOL_FILE

# find object file
_find_object() {
  local FILE=$1
  local ret=${FILE%.o}

  if [ -e $FILE ]; then
    local file_output=`file $FILE | grep 'ELF 64-bit LSB  relocatable, x86-64'`
    local readelf_output=`readelf -h $FILE | grep 'Relocatable file'`

    if [ ! -z "$file_output" ] && [ ! -z "$readelf_output" ]; then
      # remove postfix
      ret=${FILE%.*}
    fi
  fi

  echo $ret
}

ARGS="$@"

# flag to switch to the new arg parsing algorithm
USE_NEW_LINK=1

NEW_LINK_KERNEL_ARGS=""
NEW_LINK_HOST_ARGS=""
NEW_LINK_OTHER_ARGS=""
NEW_LINK_CPU_ARG=""

STATIC_LIB_LIST=()
TEMP_AR_DIRS=()

if [ $USE_NEW_LINK == 1 ]; then

# detect the verbose flags before doing anything
if [[ "$ARGS" =~ --verbose ]]; then
  VERBOSE=1
fi
#very verbose
#VERBOSE=2



# gather a list of library search paths
LIB_SEARCH_PATHS=()
for ARG in $ARGS
do
  # matches -L<path>
  if [[ "$ARG" =~ ^-L[^[:space:]]+$ ]]; then
    REAL_PATH=$(readlink -f ${ARG:2})
    if [ $VERBOSE == 2 ]; then
      echo "add library path: ${ARG:2}, canonical path: $REAL_PATH"
    fi
    LIB_SEARCH_PATHS+=( $REAL_PATH )
  fi
done




for ARG in $ARGS
do

  ####################################
  #  parse the simple switches first...
  ####################################

  if [ $ARG == "--disable-opencl" ]; then
    LOWER_OPENCL=0
    continue
  fi

  if [ $ARG == "--disable-hsa" ]; then
    LOWER_HSA=0
    continue
  fi
 
  ######################
  # Parse AMDGPU target
  ######################
  case $ARG in
    --amdgpu-target=*)
    AMDGPU_TARGET="${ARG#*=}"
    continue
    ;;
  esac

  #####################################
  # detect object or static library
  #####################################

  OBJS_TO_PROCESS=()


  if [[ "$ARG" =~ [^[:space:]]+\.cpu$ ]]; then

    cp $ARG $TEMP_DIR/kernel_cpu.o
    NEW_LINK_CPU_ARG=$NEW_LINK_CPU_ARG" "$TEMP_DIR/kernel_cpu.o
 
  elif [[ "$ARG" =~ [^[:space:]]+\.o$ ]]; then
    # detected a .o file
    if [ $VERBOSE == 2 ]; then
      echo "detect object file to process further: $ARG"
    fi

    OBJS_TO_PROCESS+=( $ARG )
  elif [[ "$ARG" =~ ^-l[^[:space:]]+$ ]] || [[ "$ARG" =~ [^[:space:]]+.a$ ]]; then

    # proccess a static library

    DETECTED_STATIC_LIBRARY=""

    # detected whether it's an -l<library naem> option
    if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then

      # expand the option into a library name
      STATIC_LIB_NAME="lib${ARG:2}.a"

      if [ $VERBOSE == 2 ]; then
        echo "looking for static library $STATIC_LIB_NAME"
      fi

      # look for the static library in the library search paths
      for LIB_PATH in "${LIB_SEARCH_PATHS[@]}"
      do
        FULL_LIB_PATH=$LIB_PATH"/"$STATIC_LIB_NAME
        FULL_LIB_PATH=$(readlink -f $FULL_LIB_PATH)
        if [ $VERBOSE == 2 ]; then
          echo "trying to detect $FULL_LIB_PATH"
        fi
        if [ -f $FULL_LIB_PATH ]; then
          if [ $VERBOSE == 2 ]; then
            echo "$FULL_LIB_PATH detected"
          fi
          DETECTED_STATIC_LIBRARY=$FULL_LIB_PATH;
          break;
        fi
      done
    else
      # this is .a static library file specified at the commad line
      if [ -f $ARG ]; then
        FULL_LIB_PATH=$(readlink -f $ARG)
        if [ $VERBOSE == 2 ]; then
          echo "use .a specified at: $FULL_LIB_PATH"
        fi
        DETECTED_STATIC_LIBRARY=$FULL_LIB_PATH
      fi
    fi  # if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then


    # check for duplicated static library options
    if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then
      for LIB in "${STATIC_LIB_LIST[@]}"
      do
        if [[ $LIB == $DETECTED_STATIC_LIBRARY ]]; then
          # this library has already been looked at, skip it
          DETECTED_STATIC_LIBRARY=""
          break;
        fi
      done
      if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then
        STATIC_LIB_LIST+=( $DETECTED_STATIC_LIBRARY )
      fi
    fi
 
    
    KERNEL_UNDETECTED="1" 
    if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then
      
      # we found a static library library
      if [ $VERBOSE == 2 ]; then
        echo "processing static library $DETECTED_STATIC_LIBRARY"
      fi

      # detect whether the objects in the static library contain a .kernel section
      KERNEL_UNDETECTED=`objdump -t $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?`
      if [[ $KERNEL_UNDETECTED == "0" ]]; then

        # .kernel section detected, extract the objects from the archieve

        if [ $VERBOSE == 2 ]; then
          echo "kernel detected in $DETECTED_STATIC_LIBRARY"
        fi

        CURRENT_DIR=$PWD
        # extract the archive
        FILE=`basename $DETECTED_STATIC_LIBRARY`
        AR_TEMP_DIR=$TEMP_DIR"/"$FILE

        if [ $VERBOSE == 2 ]; then
          echo "creating temp dir: $AR_TEMP_DIR"
        fi
 
        mkdir -p $AR_TEMP_DIR
        TEMP_AR_DIRS+=( $AR_TEMP_DIR )
        cd $AR_TEMP_DIR
        `ar x $DETECTED_STATIC_LIBRARY`

        cd $CURRENT_DIR

        # store all the extract objects to process further
        OBJS_TO_PROCESS=($(ls $AR_TEMP_DIR/*.o))

      fi  # if [[ $KERNEL_UNDETECTED == "0" ]]; then
    fi  # if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then
  elif [ -f $ARG ]; then
    # an object file but doesn't have an .o extension??
    file_output=`file $ARG | grep 'ELF 64-bit LSB  relocatable, x86-64'`
    readelf_output=`readelf -h $ARG | grep 'Relocatable file'`
    if [ ! -z "$file_output" ] && [ ! -z "$readelf_output" ]; then
      OBJS_TO_PROCESS+=( $ARG )
    fi
  fi


  # no objects to further process, pass the original args down to the host linker
  if [ ${#OBJS_TO_PROCESS[@]} == 0 ]; then
    # no objects to further process, pass the original args down to the host linker
    if [ $VERBOSE == 2 ]; then
      echo "passing down link args: $ARG"
    fi
    NEW_LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS" "$ARG
    continue
  fi

  # processs the objects we put aside
  for OBJ in "${OBJS_TO_PROCESS[@]}"
  do
    if [ $VERBOSE == 2 ]; then
      echo "processing $OBJ"
    fi

    # detect whether the objects in the static library contain a .kernel section
    KERNEL_UNDETECTED=`objdump -t $OBJ | grep -q "\.kernel"; echo $?`
    if [[ $KERNEL_UNDETECTED == "0" ]]; then

      FILE=`basename $OBJ` # remove path
      FILENAME=${FILE%.*}
      KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc
      HOST_FILE=$TEMP_DIR/$FILENAME.host.o

      # extract kernel section
      objcopy -O binary -j .kernel $OBJ $KERNEL_FILE 

      # extract host section
      objcopy -R .kernel $OBJ $HOST_FILE

      # strip all symbols specified in symbol.txt from $HOST_FILE
      objcopy @$CXXAMP_SERIALIZE_SYMBOL_FILE $HOST_FILE $HOST_FILE.new 2> /dev/null
      if [ -f $HOST_FILE.new ]; then
        mv $HOST_FILE.new $HOST_FILE
      fi

      # find cxxamp_serialize symbols and save them into symbol.txt
      objdump -t $HOST_FILE -j .text 2> /dev/null | grep "g.*__cxxamp_serialize" | awk '{print "-L"$6}' >> $CXXAMP_SERIALIZE_SYMBOL_FILE

      NEW_LINK_KERNEL_ARGS=$NEW_LINK_KERNEL_ARGS" "$KERNEL_FILE
      NEW_LINK_HOST_ARGS=$NEW_LINK_HOST_ARGS" "$HOST_FILE
    else
      NEW_LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS" "$OBJ
    fi


  done # for OBJ in "${OBJS_TO_PROCESS[@]}"
done

else #  if [ $USE_NEW_LINK == 1 ]; then

############################
# Old argument processing
############################

for ARG in $ARGS
do
  if [ -f $ARG ]; then
    FILE=`basename $ARG` # remove path
    FILENAME=$(_find_object $FILE)  # check if it's an object file
    CPUFILE=${FILE%.cpu}
    ISCRT=${ARG#/usr}    # exception for objects under /usr
    ISLIB=${ARG#/lib}    # exception for objects under /lib

    if [ $FILENAME != $FILE ] && [ $ISCRT == $ARG ] && [ $ISLIB == $ARG ]; then
      KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc
      HOST_FILE=$TEMP_DIR/$FILENAME.host.o

      # extract kernel section
      objcopy -O binary -j .kernel $ARG $KERNEL_FILE 

      # extract host section
      objcopy -R .kernel $ARG $HOST_FILE

      # strip all symbols specified in symbol.txt from $HOST_FILE
      objcopy @$CXXAMP_SERIALIZE_SYMBOL_FILE $HOST_FILE $HOST_FILE.new 2> /dev/null
      if [ -f $HOST_FILE.new ]; then
        mv $HOST_FILE.new $HOST_FILE
      fi

      # find cxxamp_serialize symbols and save them into symbol.txt
      objdump -t $HOST_FILE -j .text 2> /dev/null | grep "g.*__cxxamp_serialize" | awk '{print "-L"$6}' >> $CXXAMP_SERIALIZE_SYMBOL_FILE

      LINK_KERNEL_ARGS=$LINK_KERNEL_ARGS" "$KERNEL_FILE
      LINK_HOST_ARGS=$LINK_HOST_ARGS" "$HOST_FILE
    elif [[ $CPUFILE != $FILE ]]; then
        cp $ARG $TEMP_DIR/kernel_cpu.o
        LINK_CPU_ARG=$LINK_CPU_ARG" "$TEMP_DIR/kernel_cpu.o
    else
      LINK_OTHER_ARGS=$LINK_OTHER_ARGS" "$ARG
    fi
  elif [ $ARG == "--verbose" ]; then
    VERBOSE=1
  elif [ $ARG == "--disable-opencl" ]; then
    LOWER_OPENCL=0
  elif [ $ARG == "--disable-hsa" ]; then
    LOWER_HSA=0
  else

    ######################
    # Parse AMDGPU target
    ######################
    case $ARG in
      --amdgpu-target=*)
      AMDGPU_TARGET="${ARG#*=}"
      continue
      ;;
    esac

    #########################
    # Append other arguments
    #########################

    LINK_OTHER_ARGS=$LINK_OTHER_ARGS" "$ARG
  fi
done


if [ $VERBOSE != 0 ]; then
  echo "kernel args: "$LINK_KERNEL_ARGS
  echo ""
  echo "host args: "$LINK_HOST_ARGS
  echo ""
  echo "other args: "$LINK_OTHER_ARGS
  echo ""
fi

###################################
# End of old argument processing
###################################

fi

# AMDGPU_TARGET could be overridden by HCC_AMDGPU_TARGET env variable
if [ -n "$HCC_AMDGPU_TARGET" ]; then
  # map ISA version string to GPU family
  if [ "$HCC_AMDGPU_TARGET" = "AMD:AMDGPU:7:0:0" ]; then
    AMDGPU_TARGET="kaveri"
  elif [ "$HCC_AMDGPU_TARGET" = "AMD:AMDGPU:7:0:1" ]; then
    AMDGPU_TARGET="hawaii"
  elif [ "$HCC_AMDGPU_TARGET" = "AMD:AMDGPU:8:0:1" ]; then
    AMDGPU_TARGET="carrizo"
  elif [ "$HCC_AMDGPU_TARGET" = "AMD:AMDGPU:8:0:2" ]; then
    AMDGPU_TARGET="tonga"
  elif [ "$HCC_AMDGPU_TARGET" = "AMD:AMDGPU:8:0:3" ]; then
    AMDGPU_TARGET="fiji"
  else
    # not mappable, simply pass to backend and wish it accepts
    AMDGPU_TARGET=$HCC_AMDGPU_TARGET
  fi
fi
if [ $VERBOSE != 0 ]; then
  echo "AMDGPU target: "$AMDGPU_TARGET
  echo ""
fi


if [ $USE_NEW_LINK == 1 ]; then

if [ $VERBOSE != 0 ]; then
  echo "new kernel args: "$NEW_LINK_KERNEL_ARGS
  echo ""
  echo "new host args: "$NEW_LINK_HOST_ARGS
  echo ""
  echo "new other args: "$NEW_LINK_OTHER_ARGS
  echo ""
fi

if [ $VERBOSE != 0 ]; then
  echo "replacing old link args with new link args"
fi
LINK_KERNEL_ARGS=$NEW_LINK_KERNEL_ARGS
LINK_HOST_ARGS=$NEW_LINK_HOST_ARGS
LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS

fi


# linker return value
ret=0

# only do kernel lowering if there are objects given
if [ -n "$LINK_KERNEL_ARGS" ]; then

  # combine kernel sections together
  $LINK $LINK_KERNEL_ARGS | $OPT -always-inline - -o $TEMP_DIR/kernel.bc
  
  # lower to SPIR
  if [ $LOWER_OPENCL == 1 ]; then
    # lower to SPIR
    if [ $VERBOSE == 0 ]; then
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.spir --spir
    else
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.spir --spir --verbose
    fi
    ret=$?
    if [ $ret == 0 ]; then
      # build a new kernel object
      pushd . > /dev/null
      cd $TEMP_DIR
      $CLAMP_EMBED kernel.spir kernel_spir.o
      popd > /dev/null
    fi
  fi
  
  # lower to OpenCL C
  if [ $LOWER_OPENCL == 1 ]; then
    # lower to OpenCL C
    if [ $VERBOSE == 0 ]; then
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.cl --opencl
    else
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.cl --opencl --verbose
    fi
    ret=$?
    if [ $ret == 0 ]; then
      # build a new kernel object
      pushd . > /dev/null
      cd $TEMP_DIR
      $CLAMP_EMBED kernel.cl kernel.o
      popd > /dev/null
    fi
  fi
  
  # lower to HSA
  if [ $LOWER_HSA == 1 ]; then
    # lower to HSA BRIG
    if [ $VERBOSE == 0 ]; then
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.brig --hsa --amdgpu-target=$AMDGPU_TARGET
    else
      $CLAMP_DEVICE $TEMP_DIR/kernel.bc $TEMP_DIR/kernel.brig --hsa --amdgpu-target=$AMDGPU_TARGET --verbose
    fi
    ret=$?
    if [ $ret == 0 ]; then
      # build a new kernel object
      pushd . > /dev/null
      cd $TEMP_DIR
      $CLAMP_EMBED kernel.brig kernel_hsa.o
      popd > /dev/null
    fi
  fi

  # HSA offline finalization
  if [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 1 ]; then
    if [ -e $HOF_BIN/hof ]; then
      # conduct HSA offline finalization for APU
      $HOF_BIN/hof -output=$TEMP_DIR/kernel.isa -brig $TEMP_DIR/kernel.brig
    else
      if [ -e $HOF_BIN/amdhsafin ]; then
        case $AMDGPU_TARGET in
          #default set to fiji
          fiji)
            HOF_ARCH="8:0:3"
          ;;
          kaveri)
            HOF_ARCH="7:0:0"
          ;;
          carrizo)
            HOF_ARCH="8:0:1"
          ;;
          hawaii)
            HOF_ARCH="7:0:1"
          ;;
          tonga)
            HOF_ARCH="8:0:2"
          ;;
        esac

        # conduct HSA offline finalization for DGPU
        $HOF_BIN/amdhsafin -target=$HOF_ARCH -output=$TEMP_DIR/kernel.isa -brig $TEMP_DIR/kernel.brig -O2
      fi
    fi

    ret=$?
    if [ $ret == 0 ]; then
      # build a new kernel object
      pushd . > /dev/null
      cd $TEMP_DIR
      $CLAMP_EMBED kernel.isa kernel_hof.o
      popd > /dev/null

      # debug purpose
      # dump the brig
      KMDUMPBRIG="${KMDUMPBRIG:=0}"
      if [ $KMDUMPBRIG == "1" ]; then
        cp $TEMP_DIR/kernel.isa ./dump.isa
      fi
    fi
  fi
  
  if [ $ret == 0 ]; then
    # link everything together
    if [ $LOWER_OPENCL == 1 ] && [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 1 ]; then
      ld --allow-multiple-definition $TEMP_DIR/kernel.o $TEMP_DIR/kernel_spir.o $TEMP_DIR/kernel_hsa.o $TEMP_DIR/kernel_hof.o $LINK_HOST_ARGS $LINK_CPU_ARG $LINK_OTHER_ARGS
    elif [ $LOWER_OPENCL == 1 ] && [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 0 ]; then
      ld --allow-multiple-definition $TEMP_DIR/kernel.o $TEMP_DIR/kernel_spir.o $TEMP_DIR/kernel_hsa.o $LINK_HOST_ARGS  $LINK_CPU_ARG $LINK_OTHER_ARGS
      ret=$?
    elif [ $LOWER_OPENCL == 1 ] && [ $LOWER_HSA == 0 ]; then
      ld --allow-multiple-definition $TEMP_DIR/kernel.o $TEMP_DIR/kernel_spir.o $LINK_HOST_ARGS $LINK_CPU_ARG $LINK_OTHER_ARGS
      ret=$?
    elif [ $LOWER_OPENCL == 0 ] && [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 1 ]; then
      ld --allow-multiple-definition $TEMP_DIR/kernel_hsa.o $TEMP_DIR/kernel_hof.o $LINK_HOST_ARGS $LINK_CPU_ARG $LINK_OTHER_ARGS
    elif [ $LOWER_OPENCL == 0 ] && [ $LOWER_HSA == 1 ] && [ $LOWER_HOF == 0 ]; then
      ld --allow-multiple-definition $TEMP_DIR/kernel_hsa.o $LINK_HOST_ARGS $LINK_CPU_ARG $LINK_OTHER_ARGS
      ret=$?
    else
      echo "ERROR: No GPU target available! Linker failed."
      ret=1
    fi
  fi

fi # if [ -n $LINK_KERNEL_ARGS ];

# remove temp files
if [ -e $TEMP_DIR/kernel.o ]; then
  rm $TEMP_DIR/kernel.o
fi

if [ -e $TEMP_DIR/kernel_spir.o ]; then
  rm $TEMP_DIR/kernel_spir.o
fi

if [ -e $TEMP_DIR/kernel_hof.o ]; then
  rm $TEMP_DIR/kernel_hof.o
fi

if [ -e $TEMP_DIR/kernel_hsa.o ]; then
  rm $TEMP_DIR/kernel_hsa.o
fi

if [ -e $TEMP_DIR/kernel_cpu.o ]; then
  rm $TEMP_DIR/kernel_cpu.o
fi

if [ -e $TEMP_DIR/kernel.cl ]; then
  rm $TEMP_DIR/kernel.bc
fi

if [ -e $TEMP_DIR/kernel.spir ]; then
  rm $TEMP_DIR/kernel.spir
fi

if [ -e $TEMP_DIR/kernel.isa ]; then
  rm $TEMP_DIR/kernel.isa
fi

if [ -e $TEMP_DIR/kernel.brig ]; then
  rm $TEMP_DIR/kernel.brig
fi

if [ -e $TEMP_DIR/kernel.bc ]; then
  rm $TEMP_DIR/kernel.bc
fi

if [ -n "$LINK_KERNEL_ARGS" ]; then
  rm $LINK_KERNEL_ARGS # individual kernels
fi

if [ -n "$LINK_HOST_ARGS" ]; then
  rm $LINK_HOST_ARGS # individual host codes
fi

if [ -e $CXXAMP_SERIALIZE_SYMBOL_FILE ]; then
  rm $CXXAMP_SERIALIZE_SYMBOL_FILE # __cxxamp_serialize symbols
fi

for TD in "${TEMP_AR_DIRS[@]}"
do
  rm -rf $TD
done

if [ -d $TEMP_DIR ]; then
  rm -f $TEMP_DIR/*
  rmdir $TEMP_DIR
fi

# return value
exit $ret
